/* This file is part of FireEscape.
 *
 * FireEscape is the intellectual work of Phillip Cheng & Allen Park.
 * All future releases or modifications of this program must include this
 * attribuation as according to the Creative Commons BY-SA license.
 *
 * FireEscape is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * FireEscape is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with FireEscape.  If not, see <http://www.gnu.org/licenses/>.
 *
 * All modifications to this program should include this original statement.
 *
 * If you modify, distribute, or use the program , please contact
 * fireescape@kloudvine.com
 * http://code.google.com/p/fireescape/
 *
 * If you are interested in using FireEscape for your structure, please contact us
 * for support.
 *
 * If you do use FireEscape, please consider donating to the project.
 */
package fireescape;

import java.util.ArrayList;
import java.awt.*;
import java.awt.geom.Point2D;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author parkA
 */
public class Floor {

    //private Image floorImage;
    private double xSize;
    private double ySize;
    private ArrayList<Room> rooms;
    //private ArrayList<Exit> exits;      //only used for approaching bots to generate neighbors

    /**
     * Constructs a floor
     * @param xSiz The x width of the floor
     * @param ySiz The y length of the floor
     */
    public Floor(double xSiz, double ySiz) {
        xSize = xSiz;
        ySize = ySiz;
        rooms = new ArrayList<Room>();
        //exits = new ArrayList<Exit>();
    }

    /**
     * Resets all the rooms
     */
    public void reset() {
        for (Room r : rooms) {
            r.reset();
        }
    }

    /**
     * Gets a room
     * @param num The room ID
     * @return The room
     */
    public Room getRoom(int num) {
        return rooms.get(num);
    }

    /**
     * Returns the number of rooms
     * @return The number of rooms in this floor
     */
    public int getNumRooms() {
        return rooms.size();
    }

    /*public Image copyFloorImage() {
    return (Image) floorImage.getScaledInstance(floorImage.getWidth(null), floorImage.getHeight(null), Image.SCALE_SMOOTH);
    }*/
    /*public Image copyFloorImage() {
    return FireEscapeGUI.copyFloorImage(floorImage);
    }*/

    /*public Image paint() {
    Image copy = copyFloorImage();
    Graphics2D g = (Graphics2D) copy.getGraphics();
    for (Room r : rooms) {
    r.paintBots(g);
    }
    return copy;
    }*/
    /**
     * Paints the floor
     * @param g The Graphics2D object used to paint the floor
     */
    public void paint(Graphics2D g) {
        for (Room r : rooms) {
            r.paint(g);
        }
    }

    /**
     * Paints the rooms only
     * @param g The Graphics2D object used to paint the floor
     */
    public void paintRoomsOnly(Graphics2D g) {
        for (Room r : rooms) {
            r.paintRoom(g);
        }
    }

    /**
     * Adds an exit to the floor
     * @param exit The new exit
     * @param floorNum The floor number
     */
    public void addExit(Exit exit, int floorNum) {
        Room[] twoRooms = new Room[2];
        if (toOutside(exit)) {
            twoRooms[0] = Map.outside;
        }
        for (Room floor : rooms) {
            if (floor.exitOnRoom(exit)) {
                if (twoRooms[0] == null) {
                    twoRooms[0] = floor;
                } else if (twoRooms[1] == null) {
                    twoRooms[1] = floor;
                    if (!Map.testingNewMap) {
                        break;
                    }
                } else {                            //should never get here anymore.
                    Logger.getLogger("FireEscapeLog").log(Level.SEVERE, "Exit was matched to more than 2 rooms");
                }
            }
        }
        if (twoRooms[0] == null && twoRooms[1] == null) {
            Logger.getLogger("FireEscapeLog").log(Level.SEVERE, "Exit was not matched at all: " + exit);
        } else if (twoRooms[0] == null) {
            Logger.getLogger("FireEscapeLog").log(Level.SEVERE, "Exit was matched to wrong one: " + exit);
        } else if (twoRooms[1] == null) {
            if (Map.testingNewMap) {
                Logger.getLogger("FireEscapeLog").log(Level.FINE, "Exit was only matched to one: " + exit);
            }
            twoRooms[1] = Map.outside;
            twoRooms[0].addExit(exit);
            twoRooms[1].addExit(exit);
        } else {
            twoRooms[0].addExit(exit);
            twoRooms[1].addExit(exit);
            //addToExits(exit);
        }
    }

    /*public void addToExits(Exit exit) {
    exits.add(exit);
    }

    public int getNumExits() {
    return exits.size();
    }

    public Exit getExit(int num) {
    return exits.get(num);
    }*/
    /**
     * Returns which room the coordinates are in
     * @param x1 The first x coordinate
     * @param y1 The first y coordinate
     * @param x2 The second x coordinate
     * @param y2 The second y coordinate
     * @return The room the coordinates are in
     */
    public Room whichRoom(double x1, double y1, double x2, double y2) {
        for (Room r : rooms) {
            /*if (x1 >= r.getX() && x1 <= r.getX() + r.getWidth() &&
            y1 >= r.getY() && y1 <= r.getY() + r.getHeight() &&
            x2 >= r.getX() && x2 <= r.getX() + r.getWidth() &&
            y2 >= r.getY() && y2 <= r.getY() + r.getHeight()) {*/
            if (r.contains(x1, y1) && r.contains(x2, y2)) {
                return r;
            }
        }
        Logger.getLogger("FireEscapeLog").log(Level.FINE, "Exit is not matched to a room");
        System.out.println("Floor whichRoom");
        return null;
    }

    /**
     * Tests if an exit leads to outside
     * @param exit The exit
     * @return True if the exit leads to outside, false if not
     */
    public boolean toOutside(Exit exit) {
        return (exit.getX1() == 0 && exit.getX2() == 0) ||
                (exit.getX1() == xSize && exit.getX2() == xSize) ||
                (exit.getY1() == 0 && exit.getY2() == 0) ||
                (exit.getY1() == ySize && exit.getY1() == ySize);
    }

    /**
     * Adds a new room to the floor
     * @param x1 The x coordinate of the first corner of the new room
     * @param y1 The y coordinate of the first corner of the new room
     * @param x2 The x coordinate of the second corner of the new room
     * @param y2 The y coordinate of the second corner of the new room
     * @param roomID The room ID
     * @param floorNum The floor number
     * @param botInjectable Whether the room will accept bots starting there or not
     */
    public void addRoom(ArrayList<Point2D.Double> points, int roomID, int floorNum, boolean botInjectable) {
        rooms.add(new Room(points, roomID, floorNum, botInjectable));
    }
}
